﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using ALinq.Mapping;

using Microsoft.VisualStudio.TestTools.UnitTesting;
using NorthwindDemo;
#if L2S
using System.Data.Linq.Mapping;
#else
using ALinq.Access;
using ALinq.SQLite;
#endif

namespace TestProject
{
    [TestClass]
    public class TableMappingTest
    {
        private const string CategoryTableName = "Categories";
        private const string ProdcutTableName = "Products";

        class NorthwindMappingSource : FluentMappingSource
        {
            public NorthwindMappingSource(Action<DatabaseMapping<NorthwindDatabase>> func = null)
            {
                Map<NorthwindDatabase>(mapping =>
                {
#if L2S
                    mapping.ProviderType = typeof(System.Data.Linq.SqlClient.Sql2008Provider);
#else
                    mapping.ProviderType = typeof(AccessDbProvider);
#endif
                    mapping.Table(o => o.Categories, CategoryTableName)
                            .PrimaryKey(o => o.CategoryID)
                            .Column(o => o.CategoryName)
                            .Column(o => o.Description)
                            .Column(o => o.Picture, o => { o.DbType = "Binary"; o.CanBeNull = true; o.UpdateCheck = UpdateCheck.Never; })
                            .Association(o => o.Products, o => o.CategoryID, o => o.CategoryID);

                    mapping.Table(o => o.Products, ProdcutTableName)
                            .PrimaryKey(o => o.ProductID)
                            .Column(o => o.ProductName)
                            .Column(o => o.CategoryID)
                            .Association(o => o.Category, o => o.CategoryID, o => o.CategoryID);

                    if (func != null)
                        func(mapping);
                });
            }
        }

        [TestMethod]
        public void TablesCount()
        {
            var mappingSource = new NorthwindMappingSource();
            var model = mappingSource.GetModel(typeof(NorthwindDatabase));
            Assert.IsNotNull(model);
            var tables = model.GetTables();
            Assert.AreEqual(2, tables.Count());

            var table = model.GetTable(typeof(Category));
            Assert.IsNotNull(table);
        }

        [TestMethod]
        public void DataMembersCount()
        {
            var mappingSource = new NorthwindMappingSource();
            var model = mappingSource.GetModel(typeof(NorthwindDatabase));
            Assert.IsNotNull(model);
            var tables = model.GetTables().ToArray();
            var table0 = tables[0];
            var table1 = tables[1];

            Assert.AreEqual(5, table0.RowType.DataMembers.Count);
            Assert.AreEqual(4, table1.RowType.DataMembers.Count);
        }

        [TestMethod]
        public void AppendTable()
        {
            var mappingSource = new NorthwindMappingSource();
            var model = mappingSource.GetModel(typeof(NorthwindDatabase));
            var tablesCount1 = model.GetTables().Count();
            mappingSource = new NorthwindMappingSource(mapping =>
            {
                mapping.Table(o => o.Employees)
                       .PrimaryKey(o => o.EmployeeID)
                       .Column(o => o.Address);
            });
            model = mappingSource.GetModel(typeof(NorthwindDatabase));
            var tablesCount2 = model.GetTables().Count();
            Assert.AreEqual(tablesCount2, tablesCount1 + 1);
        }

        [TestMethod]
        public void ModifyTableName()
        {
            var mappingSource = new NorthwindMappingSource();
            var model = mappingSource.GetModel(typeof(NorthwindDatabase));
            var tableName = model.GetTable(typeof(Category)).TableName;
            var newTableName = "New" + tableName;

            mappingSource = new NorthwindMappingSource(mapping =>
            {
                mapping.Table(o => o.Categories, newTableName);
            });
            model = mappingSource.GetModel(typeof(NorthwindDatabase));
            tableName = model.GetTable(typeof(Category)).TableName;
            Assert.AreEqual(newTableName, tableName);
            //model.GetTable().RowType.DataMembers[0].Member
        }

        [TestMethod]
        public void RemoveTable()
        {
            var mappingSource = new NorthwindMappingSource();
            MetaModel model = mappingSource.GetModel(typeof(NorthwindDatabase));
            var tablesCount1 = model.GetTables().Count();

            mappingSource = new NorthwindMappingSource(mapping =>
            {
                var table = mapping.GetTable(typeof(Category));
                mapping.Tables.Remove(table);

            });
            model = mappingSource.GetModel(typeof(NorthwindDatabase));
            var tablesCount2 = model.GetTables().Count();

            Assert.AreEqual(tablesCount1 - 1, tablesCount2);
        }

        [TestMethod]
        public void DefaultTableName()
        {
            var mappingSource = new FluentMappingSource();
            mappingSource.Map<NorthwindDatabase>(mapping =>
            {
                mapping.Table(o => o.Categories);
            });
            var metaModel = mappingSource.GetModel(typeof(NorthwindDatabase));
            var metaTable = metaModel.GetTable(typeof(Category));
            Assert.IsNotNull(metaTable.TableName);
            Assert.AreEqual(typeof(Category).Name, metaTable.TableName);
        }

#if !L2S
        [TestMethod]
        public void SelectFullRow()
        {
            var mappingSource = new NorthwindMappingSource();
            var db = new NorthwindDatabase(mappingSource) { Log = Console.Out };
            db.Categories.ToArray();
        }
#endif
    }
}
